/***************************************************************************
 *   Copyright (C) 2008 by Camille Gallet, Rémy Hubscher, Regis Strub,     *
 *                         Ali Abdou                                       *
 *                                                                         *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

 #include "plInterface.hpp"


 PlInterface::PlInterface(QString fn){
    e=new PlEngine("");//Make an instance of the SWI-Prolog engine to execute the requests
    PlTerm f=PlTerm((const char*)fn.toLatin1());
    int result = PlCall("consult", f);//"compile" the script
    if(!result){
            throw(new PlException(f));
    }
 }

/*void PlInterface::loadFile(Qstring fn){


}*/

/* ****************************************************************************************************************** */



 QVector<QVector<QString> > PlInterface::plExecute(QString predicat, const QVector<QString>& args, int nbLinesMax){
      QVector<QVector<QString> > res;
      QString argv;
      int argc=args.size();
      int result,nbLines=0;
      bool is_there_null=false,stop;//if is_there_null is false the predicate will return yes or no
      QString arg;
      QStringList tabarg;
      PlTermv argspl(argc);

      //convert the args list vector into one string readable by prolog
      for (int i=0 ; i<argc ; i++){
              if(!args[i].isNull()){
                 if (i==0) 
                    argv+=args[i];
                 else
                    argv+="," + args[i];
              }else{
                 is_there_null=true;
                 if (i==0) 
                    argv+=QString("X%1").arg(i);//Xi is an uninstanciate variable
                 else
                    argv+="," + QString("X%1").arg(i);
              }
      }


          QString query = predicat + "(" + argv + ")";

          argspl = PlTermv(PlCompound((const char*) query.toLatin1()));
          PlQuery myQuery( "call", argspl);

          //store the solution(s) found if any
          result = myQuery.next_solution();
          QVector<QString> tmprep;
          
          stop=false;
          while (result && !stop){//for each solutions
          tmprep.clear();
          //convert the vector of result into QT-type

          QString tmpres=QString((char *)argspl[0]).mid(predicat.length()+1);
          tmpres = tmpres.mid(0,tmpres.length()-1);

          QVector<QString> tabarg;
          int in_list=0;//the level of list
          QString tmpstr="";
          //explode the string returned into a QVector of arguments tabarg
          for (int i=0 ; i<tmpres.size() ; i++){
               if (tmpres[i]=='['){
                  tmpstr[i]=tmpres[i];
                  in_list++;
               }else if (tmpres[i]==']'){
                  tmpstr[i]=tmpres[i];
                  in_list--;
               }else if(tmpres[i]==',' and in_list==0){
                  tabarg.append(tmpstr);
                  tmpstr="";
              }else{
                 tmpstr[i]=tmpres[i];
              }
          }
          tabarg.append(tmpstr);

          if(tabarg.size()>0)//we only append non-empy lines
              res.append(tabarg);
          result = myQuery.next_solution();
          nbLines++;
          stop=(nbLines==nbLinesMax);
      }

      //Yes/No answers
      if(nbLines==1 && (!is_there_null || res.size()==0)){//it's mean that the predicate has returned yes
           tmprep.clear();
           res.clear();
           tmprep.append("yes");
           res.append(tmprep);
      }else if(nbLines==0){//the predicate has returned no
           tmprep.clear();
           tmprep.append("no");
           res.append(tmprep);
      }

      return res;
 }
